#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define LISTEN_SZ 10

// 服务端接收程序 接收时， 分两次接受， 第一次是数据长度， 第二次是接受数据
int main(int argc, char const *argv[])
{
    int sfd, cfd, ret;
    int length;
    struct sockaddr_in svr_addr, cli_addr;
    char buffer[1024] = {0};
    ssize_t rbytes;
    int total_received; // 表示已经接收的数据
    sfd = socket(AF_INET, SOCK_STREAM, 0);
    bzero(&svr_addr, sizeof(struct sockaddr_in));
    svr_addr.sin_family = AF_INET;
    svr_addr.sin_port = htons(atoi(argv[2]));
    svr_addr.sin_addr.s_addr = inet_addr(argv[1]);
    
    //bind
    ret = bind(sfd, (struct sockaddr *)&svr_addr, sizeof(struct sockaddr_in));
    if (ret == -1) {
        perror("bind error");
        close(sfd);
        exit(EXIT_FAILURE);
    }

    // listen
    ret = listen(sfd, LISTEN_SZ);
    if (ret == -1) {
        perror("listen error");
        close(sfd);
        exit(EXIT_FAILURE);
    }
    socklen_t len = sizeof(cli_addr);
    cfd = accept(sfd, (struct sockaddr *)&cli_addr, &len);
    if (cfd == -1) {
        perror("accept error");
        close(sfd);
        exit(EXIT_FAILURE);
    }
    // 打印接收的端口和ip
    printf("client ip: %s, port: %d\n", inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port));
    while(1) {
        length = 0;
        total_received = 0; 
        // 先接受一次数据长度
        rbytes = recv(cfd, &length, 4, 0);
        if (rbytes == -1) {
            perror("recv error");
            close(cfd);
            exit(EXIT_FAILURE);
        }
        //循环接收后续数据
        for(;;) {
            rbytes = recv(cfd, buffer + total_received, length - total_received, 0);
            if(rbytes == -1) {
                perror("recv error");
                close(cfd);
                exit(EXIT_FAILURE);
            } else if (rbytes > 0) {
                printf("received buffer : %s\n", buffer);
                total_received += rbytes;
                // 当前接收的字节数如果等于数据长度，
                if (total_received == length) {
                    break;
                }
            } else if (rbytes == 0) {
                // 表示客户端已经断开了
                printf("client has closed\n");
                break;
            }
        }
        printf("buffer = %s\n", buffer);
        sleep(1);
            
        
    }

    return 0;
}
